package smartcrud.spring.controllers.rbac;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import smartcrud.common.orm.Page;
import smartcrud.common.orm.PropertyFilter;
import smartcrud.common.orm.jdbc.JdbcUtils;
import smartcrud.spring.controllers.rbac.editor.RoleEditor;
import smartcrud.spring.models.rbac.Role;
import smartcrud.spring.models.rbac.RoleService;
import smartcrud.spring.models.rbac.User;
import smartcrud.spring.models.rbac.UserService;

/**
 * Rails 1.2中对REST的实现默认把controller中的方法限制在7个：<br>
 * index、show、new、edit、create、 update和destroy.<br>
 * 而根据SpringSide4,使用Restful风格的Urls:<br>
 * 
 * <pre>
 * List page     : GET  /user/ 
 * List page     : GET  /user/{id}
 * Create page   : GET  /user/create
 * Create action : POST /user/create
 * Update page   : GET  /user/update/{id}
 * Update action : POST /user/update
 * Delete action : GET  /user/delete
 * </pre>
 * 
 * @author cyper.yin
 * 
 */
@Controller("userController")
@RequestMapping(value = "/user")
public class UserController {
	private final static Map<String,String> statusList = new TreeMap<String,String>();
	static{
		statusList.put("0", "未激活");
		statusList.put("1","正常");
		statusList.put("2","禁用");
	}
	private final static Map<String,String> sexList = new TreeMap<String,String>();
	static{
		sexList.put("1", "男");
		sexList.put("2","女");
	}

	private static final String SUCCESS = "redirect:/user/";

	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	

	@RequestMapping(value = "")
	public String index(
			@RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
			Model model, 
			HttpServletRequest request) {
		
		List<PropertyFilter> filters = JdbcUtils.buildPropertyFilters(request);
		
		Page<User> page = new Page<User>(5);
		page.setPageIndex(pageIndex);
		page = userService.findByPage(page,filters);
		
		
		model.addAttribute("page", page);
		
		return "user/user_index";
	}

	@RequestMapping("/{id}")
	public ModelAndView show(@PathVariable("id") Long id) {
		User user = userService.findUserById(id);
		ModelAndView mv = new ModelAndView("user/user_show");
		mv.addObject(user);

		return mv;
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String createForm(ModelMap model) {
		List<Role> roleList = roleService.findAllRoles();
		model.addAttribute("roleList",roleList);
		model.addAttribute("sexList", sexList);
		model.addAttribute("statusList", statusList);
		
		User user = new User();
		user.setSex("1");
		user.setStatus((byte) 2);
		model.addAttribute(user);
		return "user/user_new";
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	public String create(@ModelAttribute("user") User user,
			RedirectAttributes redirectAttributes) {
		userService.createUser(user);
		redirectAttributes.addFlashAttribute("message", "create success!");

		return SUCCESS;
	}
	@InitBinder
	protected void initBinder(
			WebDataBinder binder) throws ServletException {
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
        
        //@see http://forum.springsource.org/showthread.php?59612-Service-injection-amp-PropertyEditor
        binder.registerCustomEditor(Role.class, new RoleEditor());
	}
	
	@RequestMapping(value = "update/{id}", method = RequestMethod.GET)
	public String updateForm(Model model, @PathVariable("id") Long id) {
		List<Role> roleList = roleService.findAllRoles();
		model.addAttribute("roleList",roleList);
		
		User user = userService.findUserById(id);
		model.addAttribute("user",user);
		model.addAttribute("sexList", sexList);
		model.addAttribute("statusList", statusList);
		return "user/user_edit";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	public String update(@ModelAttribute("user") User user,
			RedirectAttributes redirectAttributes) {
		userService.updateUser(user);
		redirectAttributes.addFlashAttribute("message", "update success!");
		return SUCCESS;
	}

	@RequestMapping(value = "delete/{id}")
	public String delete(@PathVariable("id") Long id,
			RedirectAttributes redirectAttributes) {
		userService.deleteUser(id);
		redirectAttributes.addFlashAttribute("message", "delete success!");
		return SUCCESS;
	}
}
